﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace N2.ComponentModel
{
	using Details;
	
	//see ArrayConverter
	public class DetailCollectionDictionaryConverter : CollectionConverter
	{
		public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
		{
			if ((destinationType == typeof(string)) && (value is IDictionary)) {
				return
					string.Join(";",
						(value as IDictionary).Keys.Cast<string>().ToArray()
					);
			}

			return base.ConvertTo(context, culture, value, destinationType);
		}

		public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
		{
			PropertyDescriptor[] _properties = null;
			var _dictionary = value as IDictionary<string, DetailCollection>;
			
			if (null != _dictionary) {
				Type _dictionaryType = _dictionary.GetType();

				_properties = (
					from _kvp in _dictionary
					select new DetailCollectionPropertyDescriptor(
						_dictionaryType,
						_kvp.Value)).ToArray();
			}
			
			return new PropertyDescriptorCollection(_properties);
		}

		public override bool GetPropertiesSupported(ITypeDescriptorContext context)
		{
			return true;
		}

		#region Types

		class DetailCollectionPropertyDescriptor : TypeConverter.SimplePropertyDescriptor
		{
			readonly string CollectionName;
			
			public DetailCollectionPropertyDescriptor(
				Type dictionaryType,
				DetailCollection collection)
				: base(dictionaryType, collection.Name, typeof(DetailCollection), null)
			{
				this.CollectionName = collection.Name;
			}

			public override object GetValue(object component)
			{
				var _dictionary = component as IDictionary<string, DetailCollection>;

				return
					null != _dictionary
						? _dictionary[this.CollectionName]
						: null;
			}

			public override void SetValue(object component, object value)
			{
				var _dictionary = component as IDictionary<string, DetailCollection>;

				if(null != _dictionary) {
					var _value = value as DetailCollection;
					_dictionary[_value.Name] = _value;
				}
			}
		}

		#endregion Types
	}
}
